﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Qiang.QMath
{
    /// <summary>
    /// 超矩形。
    /// 目前的理解是：由于点有可能是二维的也有可能是三维的甚至是多维的，比如三维点，忽略其中第三维，只计算两个点前两维的距离，前两维构成一个平面
    /// 两维点忽略一维，只剩另一维即直线
    /// </summary>
    public class KdRect : ICloneable
    {

        public KdRect(KdPoint min, KdPoint max)
        {
            this.min = min.Clone() as KdPoint;
            this.max = max.Clone() as KdPoint;
        }


        internal KdPoint min;

        public KdPoint Min
        {
            get { return min; }
            set { min = value; }
        }

        internal KdPoint max;

        public KdPoint Max
        {
            get { return max; }
            set { max = value; }
        }



        /// <summary>
        /// 获取一个无限大的超矩形。不知道这个是什么意义
        /// </summary>
        /// <param name="k">维度</param>
        /// <returns></returns>
        public static KdRect InfiniteKdRect(int k)
        {
            KdPoint min = new KdPoint(k);
            KdPoint max = new KdPoint(k);

            for (int i = 0; i < k; i++)
            {
                min[i] = double.NegativeInfinity;
                max[i] = double.PositiveInfinity;
            }

            return new KdRect(min, max);
        }


        /// <summary>
        /// 求这个超矩形上距离点pt最近的点
        /// </summary>
        /// <param name="pt"></param>
        /// <returns></returns>
        public KdPoint Colsest(KdPoint pt)
        {
            int k = pt.NumDimensions;  //维度

            KdPoint result = new KdPoint(k);

            for (int i = 0; i < k; i++)
            {
                if (pt[i] <= this.min[i])
                {
                    result[i] = this.min[i];
                }
                else if (pt[i] >= this.max[i])
                {
                    result[i] = this.max[i];
                }
                else
                {
                    result[i] = pt[i];
                }
            }

            return result;

        }


        public KdRect Copy()
        {
            return new KdRect(this.min, this.max);
        }


        public object Clone()
        {
            return new KdRect(this.min, this.max);
        }


    }
}
